/* 
 * This file part of cget - A libcurl based downloading tool.
 * http://lianwei3.googlepages.com/home2
 * Copyright (C) 2006 Wei Lian <lianwei3@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "header.h"
#include "parseheader.h"
size_t ParseHeader::my_header_func(char *ptr, size_t size, size_t nmemb,
				   struct ThreadInfo *info)
{
//    printf("%s", ptr);
    if (strncmp(ptr, "213", 3) == 0) {
	info->length = strtoll(ptr + 4, NULL, 0);
    }
    return size * nmemb;
}


void *ParseHeader::download_header(void *stream)
{
    struct ThreadInfo *info = (struct ThreadInfo *) stream;

    CURL *curl = info->curl;
    curl_easy_setopt(curl, CURLOPT_URL, info->url);
    if (strncmp(info->url, "ftp", 3) == 0) {
	curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, my_header_func);
	curl_easy_setopt(curl, CURLOPT_WRITEHEADER, info);
	curl_easy_setopt(curl, CURLOPT_RANGE, "0-0");
	curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD,
			 CURLFTPMETHOD_NOCWD);
    } else
	curl_easy_setopt(curl, CURLOPT_NOBODY, TRUE);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,TRUE);///redirect
    curl_easy_setopt(curl, CURLOPT_USERAGENT,
		     "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
    curl_easy_perform(curl);
    if (strncmp(info->url, "ftp", 3) == 0) {
    } else {
	double length;
	curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length);
	info->length = (off_t) length;
    }

    return NULL;
}

void ParseHeader::get_file_length(std::vector <
				  struct ThreadInfo >*vec_info)
{
    int error;
    for (uint i = 0; i < vec_info->size(); i++) {
	error =
	    pthread_create(vec_info->at(i).thread, NULL,
			   download_header, &(vec_info->at(i)));
	assert(error == 0);
    }
    for (uint i = 0; i < vec_info->size(); i++) {
	error = pthread_join(*(vec_info->at(i).thread), NULL);
	assert(error == 0);
	///reset parameters for later download
	curl_easy_reset(vec_info->at(i).curl);
    }
    /// zero length check 
    if (vec_info->at(0).length == 0) {
	printf
	    ("The file you try to download has no file length description\n");
	exit(1);
    }
    /// length consistency check
    for (uint i = 1; i < vec_info->size(); i++) {
	if (vec_info->at(i).length != vec_info->at(0).length) {
	    printf("file lengthes are inconsistent with each other\n");
	    exit(1);
	}
    }
}
